﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using Super.Common;
using Super.Mvc;
using Super.MvcControl;

namespace System.Web.Mvc.Html
{
    /// <summary>
    /// DWZ风格的Html控件（在视图中使用的HTML扩展）
    /// </summary>
    public static class DWZHtmlHelperExtensions
    {
        #region 文本框输入控件
        /// <summary>
        /// DWZ风格的文本框输入控件
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="name">字段名称</param>
        /// <param name="value">字段值</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZTextBox(this HtmlHelper htmlHelper, string name, string labelText = "", object value = null, object htmlAttributes = null)
        {
            var label = LabelExtensions.Label(htmlHelper, name, labelText);
            var control = InputExtensions.TextBox(htmlHelper, name, value, htmlAttributes ?? new { style = "width: 100px" });

            return DWZInputHelper(htmlHelper, label, control, name);
        }

        /// <summary>
        /// DWZ风格的文本框输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,string labelName, object htmlAttributes = null)
        {
            return DWZTextBoxFor(htmlHelper, expression,labelName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), null);
        }

        /// <summary>
        /// DWZ风格的文本框输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string labelName,string button, object htmlAttributes = null)
        {
            return DWZTextBoxFor(htmlHelper, expression,labelName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes),button);
        }

        /// <summary>
        /// DWZ风格的文本框输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,string labelName, IDictionary<string, object> htmlAttributes, string button)
        {
            // 获取 Label 标签的HTML
          //  var label = LabelExtensions.LabelFor(htmlHelper, expression);

            var label = new MvcHtmlString("<label>"+labelName+"：</label>");

            // 增加 style="width:200px;"
            var attr = htmlAttributes ?? new Dictionary<string, object>();
            AddClass(attr, "textInput");
            //AddStyle(attr, "width", "200px");

            // 获取 TextBox 控件的HTML
            var control = InputExtensions.TextBoxFor<TModel, TProperty>(htmlHelper, expression, htmlAttributes);

            // 获取 TextBox 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // <p><label for="Name">字典项值</label><input type="text" style="width:200px;" name="Name" id="Name"></p>
            return DWZInputHelper(htmlHelper, label, control, controlName, MvcHtmlString.Create(button));
        }
        #endregion

        #region 密码文本框输入控件

        /// <summary>
        /// DWZ风格的密码文本框输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZPasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,string labelName, object htmlAttributes = null)
        {
            return DWZPasswordFor(htmlHelper, expression, labelName,HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的密码文本框输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZPasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string labelName,IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            var label = new MvcHtmlString("<label>" + labelName + "：</label>");
            // 增加 style="width:200px;"
            var attr = htmlAttributes ?? new Dictionary<string, object>();
            AddClass(attr, "textInput");
            //AddStyle(attr, "width", "200px");

            // 获取 TextBox 控件的HTML
            var control = InputExtensions.PasswordFor<TModel, TProperty>(htmlHelper, expression, htmlAttributes);

            // 获取 TextBox 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // <p><label for="Name">字典项值</label><input type="password" style="width:200px;" name="Name" id="Name"></p>
            return DWZInputHelper(htmlHelper, label, control, controlName);
        }
        #endregion

        #region 多行文本框(文本域)输入控件

        /// <summary>
        /// DWZ风格的多行文本框(文本域)输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZTextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,string labelName ,object htmlAttributes = null)
        {
            return DWZTextAreaFor(htmlHelper, expression, labelName,HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的多行文本框(文本域)输入控件
        /// </summary>
        /// <typeparam name="TModel">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="Name">字典项值</label>
        ///         <input type="text" style="width:200px;" name="Name" id="Name">
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZTextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string labelName, IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            //var label = LabelExtensions.LabelFor(htmlHelper, expression);
            var label = new MvcHtmlString("<label>" + labelName + "：</label>");
            // 增加 class="date" 和 style="width:200px;"
            var attr = htmlAttributes ?? new Dictionary<string, object>();
            //AddStyle(attr, "width", "580px");
            AddClass(attr, "longtextInput");
            AddAttribute(attr, "rows", "4");

            // 获取 TextArea 控件的HTML
            var control = TextAreaExtensions.TextAreaFor<TModel, TProperty>(htmlHelper, expression, htmlAttributes);

            // 获取 TextArea 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // <p><label for="Name">字典项值</label><input type="text" style="width:200px;" name="Name" id="Name"></p>
            var html = DWZInputHelper(htmlHelper, label, control, controlName);
            return MvcHtmlString.Create(html.ToHtmlString().Replace("<p>", "<p class=\"nowrap\">"));
        }
        #endregion

        #region lookup文本输入框

        /// <summary>
        /// DWZ风格的lookup文本输入框
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="StartDate">日期</label>
        ///         <input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date" />
        ///         <a href="javascript:;" class="inputDateButton">选择</a>
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZLookup(this HtmlHelper htmlHelper, string labelName, string groupName, string url, object htmlAttributes = null)
        {
            return DWZLookup(htmlHelper, labelName, groupName, url, "id", HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的lookup文本输入框
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="StartDate">日期</label>
        ///         <input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date" />
        ///         <a href="javascript:;" class="inputDateButton">选择</a>
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZLookup(this HtmlHelper htmlHelper, string labelName,string groupName, string url, string lookupPk, IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            var label = new MvcHtmlString("<label>" + labelName + "：</label>");

            // 增加 style="width:200px;"
            var attr = htmlAttributes ?? new Dictionary<string, object>();
            AddStyle(attr, "width", "200px");
            AddAttribute(attr, "lookupgroup", groupName);

            // 获取 TextBox 控件的HTML
            var control = InputExtensions.TextBox(htmlHelper, groupName, attr);
            string strControl = control.ToHtmlString().Replace("name=\"", string.Format("name=\"dwz.{0}.", groupName));

            // 获取 TextBox 控件的Name属性
            var controlName = groupName;

            // 增加隐藏字段
            var hidden = InputExtensions.Hidden(htmlHelper, groupName + "." + lookupPk);

            // 增加选择超链接
            TagBuilder link = new TagBuilder("a");
            link.AddCssClass("btnLook");
            link.Attributes.Add("href", url);
            link.Attributes.Add("lookupgroup", groupName);
            link.SetInnerText("查找带回");

            // <p><label for="StartDate">日期</label><input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date"><a href="javascript:;" class="inputDateButton">选择</a></p>
            return DWZInputHelper(htmlHelper, label, MvcHtmlString.Create(strControl), controlName, MvcHtmlString.Create(hidden.ToHtmlString() + link.ToString()));
        }

        #endregion

        #region 日期输入控件

        /// <summary>
        /// DWZ风格的日期输入控件
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="StartDate">日期</label>
        ///         <input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date" />
        ///         <a href="javascript:;" class="inputDateButton">选择</a>
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZDateFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format = "yyyy-MM-dd", object htmlAttributes = null)
        {
            return DWZDateFor(htmlHelper, expression, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的日期输入控件
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="StartDate">日期</label>
        ///         <input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date" />
        ///         <a href="javascript:;" class="inputDateButton">选择</a>
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZDateFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format, IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            var label = LabelExtensions.LabelFor(htmlHelper, expression);

            // 增加 class="date" 和 style="width:200px;"
            var attr = htmlAttributes ?? new Dictionary<string, object>();
            AddClass(attr, "formatdate");
            AddClass(attr, "textInput");
            //AddStyle(attr, "width", "185px");

            // 获取 TextBox 控件的HTML
            var control = InputExtensions.TextBoxFor<TModel, TProperty>(htmlHelper, expression, attr);

            // 获取 TextBox 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // 处理时间格式
            string strControl = control.ToHtmlString();
            DateTime value;
            object data = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData).Model;
            if (data != null && DateTime.TryParse(data.ToString(), out value))
            {
                strControl = strControl.Replace(value.ToString(), value.ToString(format));
            }

            //// 增加选择超链接
            //TagBuilder link = new TagBuilder("a");
            //link.AddCssClass("inputDateButton");
            //link.Attributes.Add("href", "javascript:;");
            //link.SetInnerText("选择");

            // <p><label for="StartDate">日期</label><input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date"><a href="javascript:;" class="inputDateButton">选择</a></p>
            // return DWZInputHelper(htmlHelper, label, MvcHtmlString.Create(strControl), controlName, MvcHtmlString.Create(link.ToString()));
            return DWZInputHelper(htmlHelper, label, MvcHtmlString.Create(strControl), controlName);
        }

        #endregion

        #region 下拉框选择控件

        /// <summary>
        /// DWZ风格的下拉框选择控件
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="labelName"> </param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <param name="enumItems"> </param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="StartDate">日期</label>
        ///         <input type="text" style="width: 185px;" name="StartDate" id="StartDate" class="date" />
        ///         <a href="javascript:;" class="inputDateButton">选择</a>
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumItems,string labelName,object htmlAttributes = null)
        {
            return DWZDropDownListFor(htmlHelper, expression, enumItems,labelName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的下拉框选择控件
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="defaultValue"> </param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <param name="enumItems"> </param>
        /// <param name="labelName"> </param>
        /// <example>
        /// 输入HTML如下：
        ///     <p>
        ///         <label for="StartDate">日期</label>
        ///         <input type="text" style="width: 200px;" name="StartDate" id="StartDate" class="date" />
        ///         <a href="javascript:;" class="inputDateButton">选择</a>
        ///     </p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumItems,string labelName, IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            var label = new MvcHtmlString("<label>" + labelName + "：</label>");

            IList<EnumShowExtention.SelectItem> listtemp = new List<EnumShowExtention.SelectItem>();
           // 获取枚举成员
           var values = Enum.GetValues(enumItems);
           foreach (var item in values)
           {
               listtemp.Add(new EnumShowExtention.SelectItem { Value = ((int)item).ToString(), Text = ((Enum)item).ToShow() });
           }

            // 获取下拉框的数据源
           var list = new SelectList(listtemp, "Value", "Text");

            // 获取 TextBox 控件的HTML
            var control = SelectExtensions.DropDownListFor<TModel, TProperty>(htmlHelper, expression, list, htmlAttributes);

            // 获取 TextBox 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // 
            return DWZInputHelper(htmlHelper, label, control, controlName);
        }

        #endregion

        #region 多选择框（CheckBox）

        /// <summary>
        /// DWZ风格的多选择框（CheckBox）
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <returns></returns>
        public static MvcHtmlString DWZCheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format = null, object htmlAttributes = null)
        {
            return DWZCheckBoxListFor(htmlHelper, expression, enumType, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的多选择框（CheckBox）
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <returns></returns>
        public static MvcHtmlString DWZCheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format, IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            var label = LabelExtensions.LabelFor(htmlHelper, expression);

            var control = CheckBoxListExtension.SCheckBoxListFor(htmlHelper, expression, enumType, format, htmlAttributes);

            // 获取 TextBox 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // 生成在表单用的完整HTML
            return DWZInputHelper(htmlHelper, label, control, controlName);
        }
        #endregion

        #region 单选择框（RadioButton）

        /// <summary>
        /// DWZ风格的单选择框（RadioButton）
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <returns></returns>
        public static MvcHtmlString DWZRadioListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format = null, object htmlAttributes = null)
        {
            return DWZRadioListFor(htmlHelper, expression, enumType, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// DWZ风格的单选择框（RadioButton）
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda表达式</param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <returns></returns>
        public static MvcHtmlString DWZRadioListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format, IDictionary<string, object> htmlAttributes)
        {
            // 获取 Label 标签的HTML
            var label = LabelExtensions.LabelFor(htmlHelper, expression);

            var control = CheckBoxListExtension.SRadioListFor(htmlHelper, expression, enumType, format, htmlAttributes);

            // 获取 TextBox 控件的Name属性
            var controlName = ExpressionHelper.GetExpressionText(expression);

            // 生成在表单用的完整HTML
            return DWZInputHelper(htmlHelper, label, control, controlName);
        }
        #endregion

        #region 空内容的控件，占据一个字段的位置，用于强制换行。
        /// <summary>
        /// DWZ风格的空内容的控件，占据一个字段的位置，用于强制换行。
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <example>
        /// 输入HTML如下：
        ///     <p></p>
        /// </example>
        /// <returns></returns>
        public static MvcHtmlString DWZEmptyBox(this HtmlHelper htmlHelper)
        {
            var tag = new TagBuilder("p");
            return MvcHtmlString.Create(tag.ToString());
        }

        #endregion

        #region 普通Ajax表单
        /// <summary>
        /// 普通Ajax表单
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <returns></returns>
        public static MvcForm DWZBeginForm(this HtmlHelper htmlHelper, IDictionary<string, object> htmlAttributes = null)
        {
            if (htmlAttributes == null)
            {
                htmlAttributes = new Dictionary<string, object>();
                htmlAttributes.Add("class", "pageForm required-validate");
                htmlAttributes.Add("onsubmit", "return validateCallback(this, dialogAjaxDone);");
            }

            string controllerName = htmlHelper.ViewContext.RouteData.Values["controller"].ToString();
            return FormExtensions.BeginForm(htmlHelper, "save", controllerName, FormMethod.Post, htmlAttributes);
        }

        /// <summary>
        /// 普通Ajax表单
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="htmlAttributes">HTML的属性集合</param>
        /// <returns></returns>
        public static MvcForm AjaxBeginForm(this HtmlHelper htmlHelper, string actionName = "Edit", string controllerName = "", IDictionary<string, object> htmlAttributes = null)
        {
            if (htmlAttributes == null)
            {
                htmlAttributes = new Dictionary<string, object>();
                htmlAttributes.Add("class", "pageForm required-validate");
                htmlAttributes.Add("onsubmit", "return validateCallback(this, dialogAjaxDone)");
            }

            if (string.IsNullOrEmpty(controllerName))
                controllerName = htmlHelper.ViewContext.RouteData.Values["controller"].ToString();

            return FormExtensions.BeginForm(htmlHelper, actionName, controllerName, FormMethod.Post, htmlAttributes);
        }
        #endregion
        
        #region 表单的提交按钮Bar
        /// <summary>
        /// 表单的提交按钮Bar
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <returns></returns>
        public static MvcHtmlString DWZFormBar(this HtmlHelper htmlHelper)
        {
            string submit = @"
                <li>
                    <div class=""buttonActive"">
                        <div class=""buttonContent"">
                            <button type=""submit"">保存</button>
                        </div>
                    </div>
                </li>";

            string close = @"
                <li>
                    <div class=""button"">
                        <div class=""buttonContent"">
                            <button type=""button"" class=""close"">取消</button>
                        </div>
                    </div>
                </li>";
            var divTag = new TagBuilder("div");
            divTag.AddCssClass("formBar");

            var ulTag = new TagBuilder("ul");
            ulTag.InnerHtml = submit + close;
            divTag.InnerHtml = ulTag.ToString(TagRenderMode.Normal);

            return new MvcHtmlString(divTag.ToString(TagRenderMode.Normal));
        }

        /// <summary>
        /// 普通表单的提交按钮Bar
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <returns></returns>
        public static MvcHtmlString FormBar(this HtmlHelper htmlHelper)
        {
            string submit = @"<a id=""btnSave"" class=""button"" href=""javascript:void(0);""><span>保　存</span></a>";
            string close = @"<a id=""btnCancel"" class=""button"" href=""javascript:void(0);""><span>取　消</span></a>";
            var divTag = new TagBuilder("div");
            divTag.AddCssClass("buttonpanel");
            divTag.InnerHtml = string.Format("<div style=\"float: right; margin-right: 20px;\">{0}</div>", submit + close);

            return new MvcHtmlString(divTag.ToString(TagRenderMode.Normal));
        }

        public static MvcHtmlString SubBar(this HtmlHelper htmlHelper)
        {
            string subbar =
                @" 
            <div class='subBar'>
                <ul>
                    <li><div class='buttonActive'><div class='buttonContent'><button type='submit'>检索</button></div></div></li>
                </ul>
            </div>";
            return new MvcHtmlString(subbar);
        }

        #endregion

        #region 显示枚举值对应的文本信息
        /// <summary>
        /// 显示枚举值对应的文本信息
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="enumKey"></param>
        /// <returns></returns>
        public static MvcHtmlString DWZDisplayEnumFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string enumKey)
        {
            var value = DisplayExtensions.DisplayFor(html, expression).ToString();
            var text = DependencyResolver.Current.GetService<IEnumService>().GetEnumText(enumKey, value);
            return new MvcHtmlString(text);
        }
        #endregion

        #region 显示日期对应的文本信息
        /// <summary>
        /// 显示指定格式的日期文本
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="format">时间格式</param>
        /// <returns></returns>
        public static MvcHtmlString DWZDisplayDateFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string format = "yyyy-MM-dd")
        {
            DateTime date;
            object value = DisplayExtensions.DisplayFor(html, expression);
            if (value != null)
            {
                if (DateTime.TryParse(value.ToString(), out date))
                {
                    return MvcHtmlString.Create(date.ToString(format));
                }
                else
                {
                    return MvcHtmlString.Create(value.ToString());
                }
            }
            else
            {
                return MvcHtmlString.Create(string.Empty);
            }
        }
        #endregion

        #region 表单验证
        /// <summary>
        /// 必填项
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Required(this IHtmlString strHtml)
        {
            var html = replaceClass(strHtml, "required");
            var wrapHtml = html.ToHtmlString().Replace("</p>", "<span class=\"xeasy-formItemMust\">*</span></p>");
            return MvcHtmlString.Create(wrapHtml);
            //return replaceClass(strHtml, "required");
        }

        /// <summary>
        /// 电话号码
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Phone(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "phone");
        }

        /// <summary>
        /// 邮箱地址
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Email(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "email");
        }

        /// <summary>
        /// 整数
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Digits(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "digits");
        }

        /// <summary>
        /// 浮点数
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Number(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "number");
        }

        /// <summary>
        /// 字母、数字、下划线
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Alphanumeric(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "alphanumeric");
        }

        /// <summary>
        /// 只能输入字母
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Lettersonly(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "lettersonly");
        }

        /// <summary>
        /// 网址
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Url(this IHtmlString strHtml)
        {
            return replaceClass(strHtml, "url");
        }

        /// <summary>
        /// 只读文本框
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString ReadOnly(this IHtmlString strHtml, bool IsReadOnly = true)
        {
            return ReplaceByFun(strHtml, control =>
            {
                var newControl = control;
                var classMatch = Regex.Match(control, "readonly=\"(?<name>[^\"]+)\"", RegexOptions.IgnoreCase);
                if (!classMatch.Success)
                {
                    if (IsReadOnly)
                    {
                        newControl = control.Replace("name=", string.Format("{0} name=", "readonly=\"true\""));
                    }
                }
                else
                {
                    if (!IsReadOnly)
                    {
                        newControl = control.Replace(classMatch.Groups[0].Value, "");
                    }
                }
                return newControl;
            });
        }

        /// <summary>
        /// 禁用文本框
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Disable(this IHtmlString strHtml, bool IsDisable = true)
        {
            return ReplaceByFun(strHtml, control =>
            {
                var newControl = control;
                var classMatch = Regex.Match(control, "disabled=\"(?<name>[^\"]+)\"", RegexOptions.IgnoreCase);
                if (!classMatch.Success)
                {
                    if (IsDisable)
                    {
                        newControl = control.Replace("name=", string.Format("{0} name=", "disabled=\"true\""));
                    }
                }
                else
                {
                    if (!IsDisable)
                    {
                        newControl = control.Replace(classMatch.Groups[0].Value, "");
                    }
                }
                return newControl;
            });
        }

        /// <summary>
        /// 显示水印提示
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="altText">水印提示文本</param>
        /// <returns></returns>
        public static MvcHtmlString Alt(this IHtmlString strHtml, string altText)
        {
            return replaceAttribute(strHtml, "alt", altText);
        }

        /// <summary>
        /// 最大长度
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static MvcHtmlString MaxLength(this IHtmlString strHtml, int length)
        {
            return replaceAttribute(strHtml, "maxlength", length.ToString());
        }

        /// <summary>
        /// 最小长度
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static MvcHtmlString MinLength(this IHtmlString strHtml, int length)
        {
            return replaceAttribute(strHtml, "minlength", length.ToString());
        }

        /// <summary>
        /// 判断两个控件的值是否相等，比如确认密码控件
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="controlId">控件ID</param>
        /// <returns></returns>
        public static MvcHtmlString EqualTo(this IHtmlString strHtml, string controlId)
        {
            return replaceAttribute(strHtml, "equalto", "#" + controlId);
        }

        /// <summary>
        /// 大于指定数字的值
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="number">数字</param>
        /// <returns></returns>
        public static MvcHtmlString Min(this IHtmlString strHtml, double number)
        {
            return replaceAttribute(strHtml, "min", number.ToString());
        }

        /// <summary>
        /// 小于指定数字的值
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="number">数字</param>
        /// <returns></returns>
        public static MvcHtmlString Max(this IHtmlString strHtml, double number)
        {
            return replaceAttribute(strHtml, "max", number.ToString());
        }

        /// <summary>
        /// 远程服务端验证，直接返回布尔值
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="url">远程请求服务地址</param>
        /// <returns>bool</returns>
        public static MvcHtmlString Remote(this IHtmlString strHtml, string url)
        {
            return replaceAttribute(strHtml, "remote", url);
        }

        /// <summary>
        /// 比较时间
        /// </summary>
        /// <param name="strHtml"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static MvcHtmlString CompareDate(this IHtmlString strHtml, string controlName)
        {
            return replaceAttribute(strHtml, "compareDate", "#" + controlName);
        }

        /// <summary>
        /// 将文本框控件整行显示
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString Line(this IHtmlString strHtml)
        {
            var html = strHtml.ToHtmlString().Replace("<p>", "<p style=\"width: 760px\">").Replace("200px", "580px");

            return MvcHtmlString.Create(html);
        }


        private static MvcHtmlString replaceAttribute(IHtmlString strHtml, string propName, string propValue)
        {
            return ReplaceByFun(strHtml, control =>
            {
                var newControl = control;
                var classMatch = Regex.Match(control, string.Format("{0}=\"(?<name>[^\"]+)\"", propName), RegexOptions.IgnoreCase);
                if (classMatch.Success)
                {
                    var newClass = classMatch.Groups[0].Value.Replace(classMatch.Groups[1].Value, propValue);
                    newControl = control.Replace(classMatch.Groups[0].Value, newClass);
                }
                else
                {
                    newControl = control.Replace("name=", string.Format("{0} name=", string.Format("{0}=\"{1}\"", propName, propValue)));
                }
                return newControl;
            });
        }

        private static MvcHtmlString replaceClass(IHtmlString strHtml, string className)
        {
            return ReplaceByFun(strHtml, control =>
            {
                var newControl = control;
                var classMatch = Regex.Match(control, "class=\"(?<name>[^\"]+)\"");
                if (classMatch.Success)
                {
                    var newClass = classMatch.Groups[0].Value.Replace(classMatch.Groups[1].Value, classMatch.Groups[1].Value + " " + className);
                    newControl = control.Replace(classMatch.Groups[0].Value, newClass);
                }
                else
                {
                    newControl = control.Replace("name=", string.Format("{0} name=", "class=\"" + className + "\""));
                }
                return newControl;
            });
        }

        private static MvcHtmlString ReplaceByFun(IHtmlString strHtml, Func<string, string> replaceExpression)
        {
            var html = strHtml.ToHtmlString();

            #region 替换控件的样式表（class="required"）
            var match = Regex.Match(html, "name=\"(?<name>[^\"]+)\"");
            if (match.Success)
            {
                var controlName = match.Groups[1].Value;
                var control = GetCacheControl(controlName);
                if (!string.IsNullOrEmpty(control))
                {
                    string newControl = replaceExpression(control);

                    html = html.Replace(control, newControl);
                    AddCacheControl(controlName, newControl);
                }
            }

            #endregion

            return new MvcHtmlString(html);
        }
        #endregion

        #region 生成前台UI使用的Id和Name
        public static string GetID<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
        {
            var propertyName = ExpressionHelper.GetExpressionText(expression);
            return helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(propertyName);
        }

        public static string GetName<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
        {
            var propertyName = ExpressionHelper.GetExpressionText(expression);
            return helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName);
        }
        #endregion

        #region 辅助方法，用于添加 HtmlAttributes 的相关属性
        private static void AddAttribute(IDictionary<string, object> htmlAttributes, string propName, string propValue)
        {
            if (htmlAttributes.Keys.Contains(propName))
            {
                if (htmlAttributes[propName].ToString().IndexOf(propValue) < 0)
                {
                    htmlAttributes[propName] = propValue;
                }
            }
            else
            {
                htmlAttributes.Add(propName, propValue);
            }
        }

        private static void AddClass(IDictionary<string, object> htmlAttributes, string className)
        {
            if (htmlAttributes.ContainsKey("class"))
            {
                className = htmlAttributes["class"] + " " + className;
            }
            AddAttribute(htmlAttributes, "class", className);
        }

        private static void AddStyle(IDictionary<string, object> htmlAttributes, string styleName, string styleValue)
        {
            if (htmlAttributes.Keys.Contains("style"))
            {
                if (htmlAttributes["style"].ToString().IndexOf(styleName) < 0)
                {
                    htmlAttributes["style"] = string.Format("{0}:{1};", styleName, styleValue) + htmlAttributes["style"];
                }
            }
            else
            {
                htmlAttributes.Add("style", string.Format("{0}:{1}", styleName, styleValue));
            }
        }
        #endregion

        #region 辅助方法，生成控件的HTML
        /// <summary>
        /// 获取完整输入控件的HTML
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="label"></param>
        /// <param name="control"></param>
        /// <param name="controlName"></param>
        /// <param name="button">日期、Lookup等控件的按钮</param>
        /// <returns></returns>
        private static MvcHtmlString DWZInputHelper(HtmlHelper htmlHelper, MvcHtmlString label, MvcHtmlString control, string controlName, MvcHtmlString button = null, Func<dynamic, object> format = null)
        {
            // 缓存控件HTML，在验证控件中用到
            AddCacheControl(controlName, control.ToHtmlString());

            // 控件的格式化方法，用户可以利用这个方法来定义控件外观
            if (format == null)
                format = i => "<label class=\"CheckBox\">" + i.InputHTML + i.Text + "</label>";

            TagBuilder tag = new TagBuilder("p");
            tag.InnerHtml = label.ToHtmlString() + control.ToHtmlString();
            if (button != null)
            {
                tag.InnerHtml += button.ToHtmlString();
            }
            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }
        #endregion

        #region 每次请求缓存输入控件（DWZ开头的控件），用于后期的验证处理
        private static void AddCacheControl(string key, string html)
        {

            var cacheControls = GetCacheDic();
            if (!cacheControls.ContainsKey(key))
            {
                cacheControls.Add(key, html);
            }
            else
            {
                cacheControls[key] = html;
            }
        }

        private static string GetCacheControl(string key)
        {
            var cacheControls = GetCacheDic();
            if (cacheControls.ContainsKey(key))
            {
                return cacheControls[key];
            }
            return string.Empty;
        }

        private static Dictionary<string, string> GetCacheDic()
        {
            Dictionary<string, string> cacheControls = null;
            if (HttpContext.Current.Items.Contains("__CacheControl"))
            {
                cacheControls = HttpContext.Current.Items["__CacheControl"] as Dictionary<string, string>;
            }
            else
            {
                cacheControls = new Dictionary<string, string>();
                HttpContext.Current.Items.Add("__CacheControl", cacheControls);
            }

            return cacheControls;
        }
        #endregion
     
    }

    public static class CheckBoxListExtension
    {
        #region CheckBoxList
        public static MvcHtmlString SCheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format = null, object htmlAttributes = null)
        {
            return SCheckBoxListFor(html, expression, enumType, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }
        public static MvcHtmlString SCheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format, IDictionary<string, object> htmlAttributes)
        {
            // 获取数据源
            var selectList = DependencyResolver.Current.GetService<IEnumService>().GetEnumDataSource(enumType);

            // 处理是否选中
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            var selectedValues = metadata.Model.ToString().Split(ModelConstant.MORE_SEPARATOR.ToCharArray());
            foreach (var item in selectList)
            {
                if (selectedValues.Contains(item.Value))
                {
                    item.Selected = true;
                }
            }

            return CheckBoxListFor(html, expression, selectList, format, htmlAttributes);
        }

        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format, object htmlAttributes)
        {
            return CheckBoxListFor(html, expression, selectList, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format = null, IDictionary<string, object> htmlAttributes = null)
        {
            return CheckBoxList(html, GetName(expression), selectList, format, htmlAttributes);
        }
        public static MvcHtmlString CheckBoxList(this HtmlHelper html, string name, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format, object htmlAttributes)
        {
            return CheckBoxList(html, name, selectList, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }
        public static MvcHtmlString CheckBoxList(this HtmlHelper html, string name, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format = null, IDictionary<string, object> htmlAttributes = null)
        {
            return InputListInternal(html, name, selectList, true, format, htmlAttributes);
        }
        #endregion

        #region RadioButtonList
        public static MvcHtmlString SRadioListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format = null, object htmlAttributes = null)
        {
            return SRadioListFor(html, expression, enumType, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }
        public static MvcHtmlString SRadioListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, string enumType, Func<dynamic, object> format, IDictionary<string, object> htmlAttributes)
        {
            // 获取数据源
            var selectList = DependencyResolver.Current.GetService<IEnumService>().GetEnumDataSource(enumType);

            // 处理是否选中
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            if (metadata.Model != null)
            {
                var selectedValues = metadata.Model.ToString().Split(ModelConstant.MORE_SEPARATOR.ToCharArray());
                foreach (var item in selectList)
                {
                    if (selectedValues.Contains(item.Value))
                    {
                        item.Selected = true;
                    }
                }
            }

            return RadioButtonListFor(html, expression, selectList, format, htmlAttributes);
        }

        public static MvcHtmlString RadioButtonList(this HtmlHelper html, string name, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format, object htmlAttributes)
        {
            return RadioButtonList(html, name, selectList, format, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }
        public static MvcHtmlString RadioButtonList(this HtmlHelper html, string name, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format = null, IDictionary<string, object> htmlAttributes = null)
        {
            return InputListInternal(html, name, selectList, false, format, htmlAttributes);
        }
        public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format, object htmlAttributes)
        {
            return RadioButtonList(html, GetName(expression), selectList, format, htmlAttributes);
        }
        public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, Func<dynamic, object> format = null, IDictionary<string, object> htmlAttributes = null)
        {
            return RadioButtonList(html, GetName(expression), selectList, format, htmlAttributes);
        }
        #endregion

        /// <summary>
        /// 核心方法，用于生成单选或多选框的控件
        /// </summary>
        /// <param name="html"></param>
        /// <param name="name">字段名称</param>
        /// <param name="selectList">数据源</param>
        /// <param name="allowMultiple">是否多选</param>
        /// <param name="format">自定义控件的显示外观</param>
        /// <param name="htmlAttributes">Input控件的的属性集合</param>
        /// <returns></returns>
        private static MvcHtmlString InputListInternal(HtmlHelper html, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, Func<dynamic, object> format, IDictionary<string, object> htmlAttributes)
        {
            // 根据字段名称获取控件的Id，
            string fullHtmlFieldName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            if (string.IsNullOrEmpty(fullHtmlFieldName))
            {
                throw new ArgumentException("filed can't be null or empty !", "name");
            }

            // 控件的格式化方法，用户可以利用这个方法来定义控件外观
            if (format == null)
                format = i => "<label class=\"CheckBox\">" + i.InputHTML + i.Text + "</label>";

            // 创建单选框或多选框控件
            StringBuilder strBuilder = new StringBuilder();
            foreach (var item in selectList)
            {
                // 判断Input控件是否为多选框
                TagBuilder tagBuilder = new TagBuilder("input");
                if (allowMultiple)
                {
                    tagBuilder.MergeAttribute("type", "checkbox", true);
                }
                else
                {
                    tagBuilder.MergeAttribute("type", "radio", true);
                }

                // 设置Input控件控件的值
                tagBuilder.MergeAttribute("value", item.Value, true);

                // 判断Input控件是否为选中
                if (item.Selected)
                {
                    tagBuilder.MergeAttribute("checked", "checked", true);
                }

                // 设置Input控件的名称和其它扩展属性
                tagBuilder.MergeAttribute("name", fullHtmlFieldName, true);
                tagBuilder.MergeAttributes<string, object>(htmlAttributes);

                // 格式化控件的外观
                var inputItem = new InputListItem { InputHTML = new MvcHtmlString(tagBuilder.ToString()), Text = item.Text };
                var s = format(inputItem).ToString();

                // 追加控件到
                strBuilder.Append(s);
            }
            return new MvcHtmlString(strBuilder.ToString());
        }

        /// <summary>
        /// 获取Lambda表达式的属性名称
        /// </summary>
        /// <param name="expression">Lambda表达式</param>
        /// <returns></returns>
        private static string GetName(LambdaExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            return ExpressionHelper.GetExpressionText(expression);
        }
    }

    /// <summary>
    /// 自定义控件显示外观的元数据
    /// </summary>
    public class InputListItem
    {
        public MvcHtmlString InputHTML { get; set; }
        public string Text { get; set; }
    }

    /// <summary>
    /// 实体级别的常量定义
    /// </summary>
    public class ModelConstant
    {
        /// <summary>
        /// 全路径的分隔符
        /// </summary>
        public const string FULL_PATH_SEPARATOR = ".";

        /// <summary>
        /// 多个值之间的分隔符
        /// </summary>
        public const string MORE_SEPARATOR = ",";
    }
}


